package org.shj.spark.sql

import org.apache.spark.sql.SparkSession
import scala.collection.mutable.Map

/**
 * 程序运行的几种方式：
 * 1. 在提交的命令行中加入需要依赖的 JDBC 的jar包
 * ./bin/spark-submit --master spark://192.168.1.23:7070 --class org.shj.spark.sql.DatasetFromJDBCDemo
 * --driver-class-path ./lib/mysql-connector-java-5.1.32.jar
 * --jars ./lib/mysql-connector-java-5.1.32.jar test.jar
 * 
 * 2. 如果使用 standalone cluster 模式来运行，配置 spark-env.sh ：
 * export SPARK_CLASSPATH=/opt/programs/spark-2.0-bin-hadoop-2.7/lib/mysql-connector-java-5.1.8-bin.jar
 * ./bin/spark-submit --master spark://192.168.1.23:7070 --deploy-mode-cluster --class org.shj.spark.sql.DatasetFromJDBCDemo 
 * hdfs://node22.8020/test.jar
 * 
 * ./bin/spark-submit --master yarn-client --class org.shj.spark.sql.DatasetFromJDBCDemo ./test.jar
 * 
 * 3. 在conf/spark-default.conf 里面配置：
 * spark.driver.extraClassPath=/opt/programs/spark-2.0-bin-hadoop-2.7/lib/mysql-connector-java-5.1.8-bin.jar
 * spark.executor.extraClassPath=/opt/programs/spark-2.0-bin-hadoop-2.7/lib/mysql-connector-java-5.1.8-bin.jar
 * 
 * 
 * 实际企业级开发环境中，当传统数据库数据规模特别大时，如果采用传统的DB去处理的话，一般需要把数据分成很多批次处理，且实际的处理过程
 * 可能会非常复杂,通过传统的Java EE等技术可能很难或者不方便实现处理算法。此时采用SparkSQL获得数据库的数据并进行分布式处理就
 * 可以非常好的解决该问题。但是由于Spark SQL加载DB中的数据需要时间，所以一般会在Spark SQL和具体要操作的DB之间加上一个缓冲
 * 层次。 例如： 1. 中间使用Redis，处理速度可提高甚至45倍    2. 把数据库里数据导入到HDFS。 
 *
 */
object DatasetFromJDBCDemo {
  def main(args: Array[String]): Unit = {
    val ss = SparkSession.builder().appName("DatasetFromJDBCDemo").getOrCreate()
    
    val options = Map("url"-> "jdbc:mysql://192.168.31.227:3306/test", 
                      "dbtable"-> "student",
                      "user" -> "root",
                      "password" -> "123456")
    
    val stuDf = ss.read.format("jdbc").options(options).load()
    
    options.put("dbtable", "student_score")
    val scoreDf = ss.read.format("jdbc").options(options).load()
    
    //后续 DataFrame 之间的操作详见相同包下的 DatesetTransformationDemo
    
    ss.stop()
  }
}